package cn.wen.core.db;

import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.support.v4.util.ArrayMap;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;


/**
 * 数据库操作的实现类
 */

public class DaoSupport<T> implements IDaoSupport<T> {

    private SQLiteDatabase mSqLiteDatabase;
    private Class<T> mClazz;
    private Object[] mPutMethodArgs = new Object[2];// 缓存参数
    private Map<String, Method> mPutMethods = new ArrayMap<>();// 缓存方法
    private QuerySupport<T> mQuerySupport;

    @Override
    public void init(SQLiteDatabase sqLiteDatabase, Class<T> clazz) {
        this.mSqLiteDatabase = sqLiteDatabase;
        this.mClazz = clazz;
        // 创建表
        /*"create table if not exists Person ("
                + "id integer primary key autoincrement, "
                + "name text, "
                + "age integer, "
                + "flag boolean)";*/
        StringBuilder sb = new StringBuilder("create table if not exists " + clazz.getSimpleName() + " ("
                + "id integer primary key autoincrement, ");
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            field.setAccessible(true);
            String name = field.getName();
            if (name == null || name.startsWith("$") || "serialVersionUID".equals(name)) {
                continue;
            }
            String type = DaoUtil.getColumnType(field.getType().getSimpleName());
            sb.append(name + type + ", ");

        }
        sb.delete(sb.length() - 2, sb.length());
        sb.append(")");
        String sql = sb.toString();
        mSqLiteDatabase.execSQL(sql);
    }

    @Override
    public void insert(List<T> data) {
        try {
            //开启事务
            mSqLiteDatabase.beginTransaction();
            for (T obj : data) {
                insert(obj);
            }
            //告诉数据库事务提交成功
            mSqLiteDatabase.setTransactionSuccessful();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //结束事务
            mSqLiteDatabase.endTransaction();
        }
        // 如果不关闭，数据库连接会一直存在导致内存不够用或者数据库被锁定

    }

    /**
     * 删除
     */
    @Override
    public int delete(String whereClause, String... whereArgs) {
        return mSqLiteDatabase.delete(DaoUtil.getTableName(mClazz), whereClause, whereArgs);
    }

    /**
     * 更新
     */
    @Override
    public int update(T obj, String whereClause, String... whereArgs) {
        ContentValues values = getContentValues(obj);
        return mSqLiteDatabase.update(getTableName(), values, whereClause, whereArgs);
    }

    /**
     * 查询的支持类
     *
     * @return
     */
    @Override
    public QuerySupport<T> querySupport() {
        if (mQuerySupport == null) {
            mQuerySupport = new QuerySupport<>(mSqLiteDatabase, mClazz);
        }
        return mQuerySupport;
    }


    private String getTableName() {
        return DaoUtil.getTableName(mClazz);
    }

    @Override
    public long insert(T obj) {
        ContentValues values = getContentValues(obj);
        long count = mSqLiteDatabase.insert(DaoUtil.getTableName(mClazz), null, values);
        return count;
    }

    private ContentValues getContentValues(T obj) {

        ContentValues values = new ContentValues();
        try {
            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                // 获取对象里面的字段名字
                //String key = field.getName();
                // 获取对象里面字段的值
                Object value = field.get(obj);
                mPutMethodArgs[0] = field.getName();
                mPutMethodArgs[1] = value;
                // 获取对象里面的方法
                String simpleName = field.getType().getSimpleName();
                Method method = mPutMethods.get(simpleName);
                if (method == null) {
                    method = ContentValues.class.getDeclaredMethod("put", String.class, value.getClass());
                    method.setAccessible(true);
                    mPutMethods.put(simpleName, method);
                }
                // 执行方法   values.put(key,value);
                method.invoke(values, mPutMethodArgs);

            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            mPutMethodArgs[0] = null;
            mPutMethodArgs[1] = null;
        }
        return values;
    }

    /**
     * 关闭数据库
     */
    @Override
    public void close() {
        if (mSqLiteDatabase != null && mSqLiteDatabase.isOpen()) {
            mSqLiteDatabase.close();
        }
    }

}
